wowwikifandomcom-20200223-history
Localizing an addon
Cut-n-pasted from http://forums.curse-gaming.com/showthread.php?t=259 thanks to Islorgris. Here is a "small" post to explain how basic localization for addons can be done (translated from the post on the WoW french UI customization forum). Overall, it's pretty simple, I hope this give authors some ideas of what is needed for localization and users some ideas of what kind of information is needed in order to make addon localization possible. The locale The locale is what makes it possible to know what language the interface is using and thus determine which specific code is going to be executed in a localized addon. typically, this is used in a GetLocale block: Code: if (GetLocale() "frFR") then -- things for the french client else -- for the rest, usually english since it's the default language end "frFR": french "deDE": german "enUS": english "koKR": korean Variables The whole deal doing a successful addon localization is simply using the translated interface texts (as translated ingame) in the language you want to enable for the element you want to use (texts, item names, spells, etc.). So, whenever texts (well almost) are used, they should be replaced by variables which will be set in a GetLocale block in order to give them the correct value for each locale Currently, it is best to put these in a file separate from the main code (usually name localization.lua for easy reference but any name will do). that file must then be declared in the xml part of the addon, juste before the other scripts that compose it, example: Code: If this is a modification on an existing addon and you want to submit it to the author, it's better to use english for the variables names and to prefix them with the addon name (to prevent conflicts with existing variables from the game or from other addons), keep the original strings and put them in variables too so that the author can match them with his original code (don't forget to comment). Example: Code: if (skillName "Herbalism") then GatherSkills.herbs = skillRank; elseif (skillName "Mining") then GatherSkills.mining = skillRank; end becomes: Code: if (skillName GATHERER_TRADE_HERBALISM) then GatherSkills.herbs = skillRank; elseif (skillName GATHERER_TRADE_MINING) then GatherSkills.mining = skillRank; end the GATHERER_TRADE_HERBALISM and GATHERER_TRADE_MINING variables are declared in the localization.lua file as follow: Code: if( GetLocale() "frFR" ) then -- french part GATHERER_TRADE_HERBALISM="Botanique"; GATHERER_TRADE_MINING="Minage"; else -- default, english GATHERER_TRADE_HERBALISM="Herbalism"; GATHERER_TRADE_MINING="Mining"; end As you could see in the example, you simply replace the original string between double quotes by the corresponding variable. Warning: If you need to use a localized string in the xml files, you need to keep the double quotes around the variable name. Example: Code: name="bcTM_PopupTitle" inherits="GameFontHighlight" text="TRACKMENU_TOOLTIP_MENU_TITLE" will allow to use the content of the TRACKMENU_TOOLTIP_MENU_TITLE variable for this xml element. Grammar and case sensitivity This part is usually only useful if the addon has to process sentences (extracted from the chat windows), such as in processing to keep specific parts of the string. In that case it can be necessary to add a GetLocale block since word are not always ordered in the same manner in various languages. Example: Quote: copper vein => veine de cuivre another thing linked to this is that since word placement may be different, uppercases may be applied on different words. Examples: Quote: Damaged chest => Coffre endommagÃ© Small damaged chest => Petit coffre endommagÃ© Accents This is somewhat delicate, the lua scripting language in wow deals with accents directly as unicode which means 2 things: First, it will not recognize an accent in a localized text if it's not in unicode and thus will not be able to match it to the accent that can be seen in the game interface. In the previous example, if you try to match "endommagÃ©" with the same string provided by the game, it will fail. Second, since these are unicode char, they're actually coded on several distinct characters (usually 2), which has to be taken into account for string manipulations based on length. The use of and UTF-8 compatible editor is a must if you're dealing with accented characters, otherwise they probably be converted to the local charset equivalent which will not match the ingame data. For a list of codes corresponding to various accentuated characters see http://www.allegro-c.de/unicode/zcodes.htm (page is in german but the table allows to find what's needed quite easily). For our earlier chest example, a string that will match the ingame data would look like: Quote: Coffre endommag\195\169 Some corresponding codes : à : \195\160 è : \195\168 ì : \195\172 ò : \195\178 ù : \195\185 á : \195\161 é : \195\169 í : \195\173 ó : \195\179 ú : \195\186 â : \195\162 ê : \195\170 î : \195\174 ô : \195\180 û : \195\187 ã : \195\163 ë : \195\171 ï : \195\175 õ : \195\181 ü : \195\188 ä : \195\164 ñ : \195\177 ö : \195\182 æ : \195\166 ø : \195\184 ç : \195\167 Unicode WOW can recognize unicode characters directly in any .lua file, if this file is saved in unicode format. The exact format to use is "utf-8". In order to edit any text file in utf-8, you need a text editor which supports utf-8. By default, the normal encoding for text files is usually iso8859-1. Some older editors might use the ANSI character set instead though. My preference in text file editing goes to EditPad Lite. By default, it edits using the ANSI charset, but it can convert the whole buffer to UTF-8 using the Convert/Unicode/ANSI->UTF-8 function. There are of course lots of other commercial softwares around which are able to save files in UTF-8 encoding. The single quote case Single quote is a bit of a special case, it also has it's equivalent in unicode but this is actually not always the case ingame, has to be checked experimentally. Examples: Quote: D\195\169couverte d'herbes > that match with game data Veine d'argent > this one used not to match, not true anymore in 1.2.2-4196 though. As a guideline, especially check anything coming from chat windows since that's where the special coding seems (might not be true anymore for 1.2.2-4196 versions and up) to be used most often instead of the standard single quote. Note: the Unicode equivalent of the single quote is encoded with 3 UTF-8 bytes: ’ : \226\128\153 (UCS 2019 -- RIGHT SINGLE QUOTATION MARK) It can for instance be found in the frFR locale game data for the Cri d’intimidation warrior ability (at least in 1.8.4). Check the GlobalStrings.lua for some strings, Blizzard do the job for you, check the contents of the GlobalStrings.lua file (extracted from the Interface.mpq for the basis and from the patch.mpq for the latest up to date). This file contains predifined variables whose value are directly in the client's language. A word on table ordering Most tables in WoW are organized alphabetically which means that the order the entries appear in the table depends on the translation of the individual items that compose it. Example: zone names in english clients (UK and US) for Kalimdor continent: Ashenvale, Azshara, Darkshore, etc. in the french client you have the following order: Ashenvale, Azshara, Un'Goro Crater (translated as "CratÃ¨re d'Un'Goro"), etc. 3rd entry represent a different zone. A static table supplying, say scaling values for the minimap based on zone order, would have to be "localized" in the sense that the table need to be sorted differently according to the client's locale to give correct values. Moderate yourself Not everything must have a translation, some things will not work anymore if they are translated. A classical example would be lua objects name (variables usually, functions occasionally) or xml objects (components names defined in the .xml file) that are reconstructed in order to be accessed. Example: getglobal(EN_DUR_FRAME..FrameName.."SlotLeft"):Show(); Here, we're getting an XML object to display it, the object name itself being rebuilt by appending together the variables EN_DUR_FRAME, FrameName and the "SlotLeft" character string. Since the objects names are hard-coded in the .xml file, a translation in one of the variable used will result in a failure getting the objet in localized clients. Final touch, the .toc file The .toc file allows localization by adding entries postfixed by the locale they should appear on: Example: Quote: ## Title: Gatherer ## Title-frFR: Gatherer (en francais, in french) ## Notes: Gatherer, displays stuff you gather in your minimap ## Notes-frFR: Gatherer, affiche les objets recoltes dans la minicarte The -frFR postfix indicate to a french localized client that a translation is available and should be prefered to the default (which most of the time correspond to english), if no "localized" entry exists for a specific client, the default one is displayed. Addendum (patch 1.4.0): in patch 1.4.0 a slightly cryptic comment from Slouken on the US board announce that they left the decimal point to the european value (ie a coma). The impact of this is that table index that uses a strings containing a dot do not work anymore, since that behaviour didn't exist before patch 1.4.0 on european version, caution would be avoid using dots in text index for table. Exemple: prior to patch this table was fine. 1.4.0" = ... Post patch, trying get the index content would result in an error because it was translated by the game engine to "FR 1,4,0" which of course doesn't match the index up there. Category: HOWTOs